<template>
	<!-- 聊天应用主容器 -->
	<div class="chat-container">
		<!-- 侧边栏区域：显示对话列表 -->
		<div class="sidebar">
			<!-- 侧边栏头部：包含新建对话按钮 -->
			<div class="sidebar-header">
				<!-- 新建对话按钮，点击触发createNewConversation方法 -->
				<el-button type="primary" @click="createNewConversation" class="new-chat-btn">
					<el-icon><Plus /></el-icon>
					新建对话
				</el-button>
			</div>

			<!-- 对话列表区域：显示所有历史对话 -->
			<div class="conversation-list">
				<!-- 循环渲染每个对话项 -->
				<div
					v-for="conversation in conversations"
					:key="conversation.id"
					:class="['conversation-item', { active: currentConversation?.id === conversation.id }]"
					@click="selectConversation(conversation)"
				>
					<!-- 对话标题 -->
					<div class="conversation-title">{{ conversation.title }}</div>
					<!-- 对话创建时间，通过formatTime方法格式化显示 -->
					<div class="conversation-time">{{ formatTime(conversation.createdAt) }}</div>
					<!-- 删除对话按钮，使用@click.stop阻止事件冒泡 -->
					<el-button type="danger" text size="small" @click.stop="deleteConversation(conversation.id)" class="delete-btn">
						<el-icon><Delete /></el-icon>
					</el-button>
				</div>
			</div>
		</div>

		<!-- 主聊天区域：显示当前对话内容 -->
		<div class="main-content">
			<!-- 聊天头部：显示当前对话标题 -->
			<div class="chat-header">
				<h2>{{ currentConversation?.title || "新对话" }}</h2>
			</div>

			<!-- 消息容器：显示所有聊天消息 -->
			<div class="messages-container" ref="messagesContainer">
				<!-- 循环渲染已完成的消息 -->
				<div v-for="(message, index) in currentMessages" :key="index" :class="['message', message.role]">
					<!-- 消息头像区域 -->
					<div class="message-avatar">
						<el-avatar :size="32">
							<!-- 根据消息角色显示不同图标：用户显示👤，助手显示🤖 -->
							<span v-if="message.role === 'user'">👤</span>
							<span v-else>🤖</span>
						</el-avatar>
					</div>
					<!-- 消息内容区域 -->
					<div class="message-content">
						<!-- 用户消息直接显示文本内容 -->
						<div v-if="message.role === 'user'" class="message-text">
							{{ message.content }}
						</div>
						<!-- 助手消息使用Markdown渲染 -->
						<div v-else class="message-text markdown-content" v-html="md.render(message.content)"></div>
						<!-- 停止生成标签 -->
						<div v-if="message.isStopped" class="stopped-tag">
							<el-tag size="small" type="warning">生成已停止</el-tag>
						</div>
					</div>
				</div>

				<!-- 流式消息：显示正在生成的助手回复 -->
				<div v-if="streamingMessage" class="message assistant">
					<div class="message-avatar">
						<el-avatar :size="32">🤖</el-avatar>
					</div>
					<div class="message-content">
						<!-- 渲染流式消息内容，使用Markdown -->
						<div class="message-text markdown-content streaming" v-html="md.render(streamingMessage)"></div>
						<!-- 打字光标动画效果 -->
						<div class="typing-cursor">|</div>
					</div>
				</div>

				<!-- 加载状态：显示等待助手回复的状态 -->
				<div v-if="loading && !streamingMessage" class="message assistant">
					<div class="message-avatar">
						<el-avatar :size="32">🤖</el-avatar>
					</div>
					<div class="message-content">
						<!-- 加载提示文本和图标 -->
						<div class="loading-text">
							<el-icon class="is-loading"><Loading /></el-icon>
							正在思考中...
						</div>
					</div>
				</div>
			</div>

			<!-- 输入区域：用户输入消息的界面 -->
			<div class="input-area">
				<div class="input-container">
					<!-- 多行文本输入框 -->
					<el-input
						v-model="inputMessage"
						type="textarea"
						:rows="3"
						placeholder="输入您的问题..."
						:disabled="loading"
						@keydown.enter.exact.prevent="sendMessage"
					/>
					<!-- 按钮组：包含停止生成和发送按钮 -->
					<div class="button-group">
						<!-- 停止生成按钮，仅在加载状态显示 -->
						<el-button v-if="loading" type="warning" @click="stopGenerating" class="stop-btn">
							<el-icon><Close /></el-icon>
							停止生成
						</el-button>
						<!-- 发送按钮，加载时显示加载状态 -->
						<el-button type="primary" :loading="loading" @click="sendMessage" class="send-btn">
							<el-icon><Promotion /></el-icon>
							发送
						</el-button>
					</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script setup>
	// 导入Vue 3组合式API相关函数
	import { ref, onMounted, nextTick, watch } from "vue";
	// 导入Element Plus组件库的消息和确认框组件
	import { ElMessage, ElMessageBox } from "element-plus";
	// 导入Element Plus图标组件
	import { Plus, Delete, Promotion, Loading, Close } from "@element-plus/icons-vue";
	// 导入自定义的聊天API模块
	import ChatAPI from "../api/api.js";
	// 导入LeanCloud Record API模块
	import RecordAPI from "../api/record.js";
	// 导入用户状态管理
	import { useUserStore } from "../stores/user.js";
	// 导入Markdown解析库
	import MarkdownIt from "markdown-it";

	// 响应式数据定义
	// 存储所有对话列表
	const conversations = ref([]);
	// 当前选中的对话
	const currentConversation = ref(null);
	// 当前对话的消息列表
	const currentMessages = ref([]);
	// 用户输入的消息内容
	const inputMessage = ref("");
	// 加载状态标志
	const loading = ref(false);
	// 消息容器的DOM引用
	const messagesContainer = ref(null);
	// 流式消息内容
	const streamingMessage = ref(null);
	// 用于中止请求的控制器
	const abortController = ref(null);
	// Markdown解析器实例
	const md = new MarkdownIt({
		html: true,
		linkify: true,
		typographer: true,
	});
	// 用户状态管理
	const userStore = useUserStore();

	// 组件生命周期钩子：组件挂载后执行
	onMounted(() => {
		// 检查用户是否已登录
		if (!userStore.isLoggedIn) {
			ElMessage.warning('请先登录');
			return;
		}
		// 加载对话列表
		loadConversations();
	});

	// 监听消息变化，自动滚动到底部
	watch(
		currentMessages,
		() => {
			// 等待DOM更新后滚动到底部
			nextTick(() => {
				scrollToBottom();
			});
		},
		{ deep: true } // 深度监听数组内部变化
	);

	// 方法定义
	// 加载所有对话列表
	const loadConversations = async () => {
		try {
			// 调用LeanCloud Record API获取对话列表
			const result = await RecordAPI.getRecordsByUser(userStore.userId);
			if (result.success) {
				// 更新对话列表数据
				conversations.value = result.data;
				// 如果有对话且没有当前选中的对话，默认选中第一个
				if (conversations.value.length > 0 && !currentConversation.value) {
					selectConversation(conversations.value[0]);
				}
			} else {
				ElMessage.error(result.error || "加载对话列表失败");
			}
		} catch (error) {
			// 显示错误提示
			ElMessage.error("加载对话列表失败");
		}
	};

	// 创建新对话
	const createNewConversation = async () => {
		try {
			// 调用LeanCloud Record API创建新对话
			const result = await RecordAPI.createRecord(userStore.userId);
			if (result.success) {
				// 将新对话添加到列表开头
				conversations.value.unshift(result.data);
				// 选中新创建的对话
				selectConversation(result.data);
				// 清空输入框
				inputMessage.value = "";
			} else {
				ElMessage.error(result.error || "创建新对话失败");
			}
		} catch (error) {
			ElMessage.error("创建新对话失败");
		}
	};

	// 选择并加载特定对话的详情
	const selectConversation = async (conversation) => {
		try {
			// 调用LeanCloud Record API获取对话详情
			const result = await RecordAPI.getRecordDetail(conversation.id);
			if (result.success) {
				// 更新当前对话
				currentConversation.value = result.data;
				// 更新当前消息列表
				currentMessages.value = result.data.messages;
			} else {
				ElMessage.error(result.error || "加载对话详情失败");
			}
		} catch (error) {
			ElMessage.error("加载对话详情失败");
		}
	};

	// 删除对话
	const deleteConversation = async (conversationId) => {
		try {
			// 显示确认对话框
			await ElMessageBox.confirm("确定要删除这个对话吗？", "提示", {
				confirmButtonText: "确定",
				cancelButtonText: "取消",
				type: "warning",
			});

			// 调用LeanCloud Record API删除对话
			const result = await RecordAPI.deleteRecord(conversationId);
			if (result.success) {
				ElMessage.success("删除成功");
				// 从列表中移除对话
				const index = conversations.value.findIndex((conv) => conv.id === conversationId);
				if (index !== -1) {
					conversations.value.splice(index, 1);
				}
				// 如果删除的是当前对话，清空当前对话
				if (currentConversation.value?.id === conversationId) {
					currentConversation.value = null;
					currentMessages.value = [];
				}
			} else {
				ElMessage.error(result.error || "删除失败");
			}
		} catch (error) {
			// 用户取消删除，不执行任何操作
		}
	};

	// 格式化时间显示
	const formatTime = (timeString) => {
		const date = new Date(timeString);
		const now = new Date();
		const diff = now - date;

		if (diff < 24 * 60 * 60 * 1000) {
			// 今天：显示时间（小时:分钟）
			return date.toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" });
		} else if (diff < 7 * 24 * 60 * 60 * 1000) {
			// 一周内：显示星期几
			const days = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
			return days[date.getDay()];
		} else {
			// 更早：显示月日
			return date.toLocaleDateString("zh-CN", { month: "2-digit", day: "2-digit" });
		}
	};

	// 停止生成消息
	const stopGenerating = () => {
		if (abortController.value) {
			// 中止请求
			abortController.value.abort();
			ElMessage.info("已停止生成");
		}
	};

	// 发送消息
	const sendMessage = async () => {
		// 检查输入是否为空
		if (!inputMessage.value.trim()) {
			ElMessage.warning("请输入消息内容");
			return;
		}

		// 如果没有当前对话，创建新对话
		if (!currentConversation.value) {
			await createNewConversation();
		}

		// 创建用户消息对象
		const userMessage = {
			role: "user",
			content: inputMessage.value.trim(),
		};

		// 将用户消息添加到当前消息列表
		currentMessages.value.push(userMessage);

		// 更新对话标题（如果是第一条消息）
		if (currentMessages.value.length === 1) {
			const newTitle = inputMessage.value.trim().slice(0, 20) + (inputMessage.value.trim().length > 20 ? "..." : "");
			currentConversation.value.title = newTitle;
			// 更新对话列表中的标题
			const convIndex = conversations.value.findIndex((conv) => conv.id === currentConversation.value.id);
			if (convIndex !== -1) {
				conversations.value[convIndex].title = newTitle;
			}
			// 更新LeanCloud中的对话标题
			await RecordAPI.updateRecordTitle(currentConversation.value.id, newTitle);
		}

		// 保存用户消息到LeanCloud
		await RecordAPI.addMessage(currentConversation.value.id, userMessage);

		// 保存要发送的消息并清空输入框
		const messageToSend = inputMessage.value.trim();
		inputMessage.value = "";
		// 设置加载状态
		loading.value = true;
		// 初始化流式消息
		streamingMessage.value = "";

		// 创建 AbortController 用于停止请求
		abortController.value = new AbortController();

		try {
			// 调用流式发送消息API
			const result = await ChatAPI.sendMessageStream(
				messageToSend, 
				currentConversation.value.id, 
				// 处理流式数据的回调函数
				(chunk, fullContent) => {
					streamingMessage.value = fullContent;
					scrollToBottom();
				},
				abortController.value.signal
			);

			if (result.success) {
				// 将流式消息添加到消息列表
				currentMessages.value.push(result.data);
				// 保存助手消息到LeanCloud
				await RecordAPI.addMessage(currentConversation.value.id, result.data);
			} else {
				ElMessage.error(result.error || "发送消息失败");
				// 移除用户消息
				currentMessages.value.pop();
			}
		} catch (error) {
			if (error.name === 'AbortError') {
				// 用户主动停止，不显示错误信息
				if (streamingMessage.value) {
					// 将当前流式消息添加到消息列表，并标记为停止生成
					const assistantMessage = {
						role: "assistant",
						content: streamingMessage.value,
						isStopped: true
					};
					currentMessages.value.push(assistantMessage);
					// 保存助手消息到LeanCloud
					await RecordAPI.addMessage(currentConversation.value.id, assistantMessage);
				}
			} else {
				ElMessage.error("发送消息失败");
				// 移除用户消息
				currentMessages.value.pop();
			}
		} finally {
			// 重置状态
			loading.value = false;
			streamingMessage.value = null;
			abortController.value = null;
		}
	};

	// 滚动到消息容器底部
	const scrollToBottom = () => {
		if (messagesContainer.value) {
			messagesContainer.value.scrollTop = messagesContainer.value.scrollHeight;
		}
	};
</script>

<style scoped>
	/* 聊天容器样式：使用flex布局，占满整个视口高度 */
	.chat-container {
		display: flex;
		height: 100vh;
		background-color: #f5f5f5;
	}

	/* 侧边栏样式：固定宽度，白色背景，右侧边框 */
	.sidebar {
		width: 300px;
		background-color: #fff;
		border-right: 1px solid #e0e0e0;
		display: flex;
		flex-direction: column;
	}

	/* 侧边栏头部样式：内边距，底部边框 */
	.sidebar-header {
		padding: 20px;
		border-bottom: 1px solid #e0e0e0;
	}

	/* 新建对话按钮样式：占满宽度 */
	.new-chat-btn {
		width: 100%;
	}

	/* 对话列表样式：占据剩余空间，可垂直滚动 */
	.conversation-list {
		flex: 1;
		overflow-y: auto;
		padding: 10px 0;
	}

	/* 对话项样式：相对定位，内边距，鼠标指针，底部边框，过渡效果 */
	.conversation-item {
		position: relative;
		padding: 12px 20px;
		cursor: pointer;
		border-bottom: 1px solid #f0f0f0;
		transition: background-color 0.2s;
	}

	/* 对话项悬停效果：浅灰色背景 */
	.conversation-item:hover {
		background-color: #f8f9fa;
	}

	/* 对话项激活状态：蓝色背景，右侧蓝色边框 */
	.conversation-item.active {
		background-color: #e3f2fd;
		border-right: 3px solid #1976d2;
	}

	/* 对话标题样式：中等字重，底部外边距，深灰色文字 */
	.conversation-title {
		font-weight: 500;
		margin-bottom: 4px;
		color: #333;
	}

	/* 对话时间样式：小号字体，浅灰色文字 */
	.conversation-time {
		font-size: 12px;
		color: #666;
	}

	/* 删除按钮样式：绝对定位，右侧，垂直居中，默认透明，过渡效果 */
	.delete-btn {
		position: absolute;
		right: 10px;
		top: 50%;
		transform: translateY(-50%);
		opacity: 0;
		transition: opacity 0.2s;
	}

	/* 悬停时显示删除按钮 */
	.conversation-item:hover .delete-btn {
		opacity: 1;
	}

	/* 主内容区域样式：占据剩余空间，垂直布局，白色背景 */
	.main-content {
		flex: 1;
		display: flex;
		flex-direction: column;
		background-color: #fff;
	}

	/* 聊天头部样式：内边距，底部边框 */
	.chat-header {
		padding: 20px;
		border-bottom: 1px solid #e0e0e0;
		background-color: #fff;
	}

	/* 聊天头部标题样式：无外边距，深灰色文字，18px字体大小 */
	.chat-header h2 {
		margin: 0;
		color: #333;
		font-size: 18px;
	}

	/* 消息容器样式：占据剩余空间，可垂直滚动，内边距，浅灰色背景 */
	.messages-container {
		flex: 1;
		overflow-y: auto;
		padding: 20px;
		background-color: #fafafa;
	}

	/* 消息样式：flex布局，底部外边距，淡入动画 */
	.message {
		display: flex;
		margin-bottom: 20px;
		animation: fadeIn 0.3s ease-in;
	}

	/* 用户消息样式：反向排列（头像在右侧） */
	.message.user {
		flex-direction: row-reverse;
	}

	/* 消息头像样式：左右外边距 */
	.message-avatar {
		margin: 0 12px;
	}

	/* 消息内容样式：最大宽度70% */
	.message-content {
		max-width: 70%;
	}

	/* 用户消息内容样式：右对齐 */
	.message.user .message-content {
		text-align: right;
	}

	/* 消息文本样式：白色背景，内边距，圆角，阴影，行高，自动换行 */
	.message-text {
		background-color: #fff;
		padding: 12px 16px;
		border-radius: 12px;
		box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
		line-height: 1.5;
		word-wrap: break-word;
	}

	/* 用户消息文本样式：蓝色背景，白色文字 */
	.message.user .message-text {
		background-color: #1976d2;
		color: white;
	}

	/* 加载文本样式：flex布局，垂直居中，间距，浅灰色文字，斜体 */
	.loading-text {
		display: flex;
		align-items: center;
		gap: 8px;
		color: #666;
		font-style: italic;
	}

	/* 输入区域样式：内边距，顶部边框 */
	.input-area {
		padding: 20px;
		border-top: 1px solid #e0e0e0;
		background-color: #fff;
	}

	/* 输入容器样式：flex布局，间距，底部对齐 */
	.input-container {
		display: flex;
		gap: 12px;
		align-items: flex-end;
	}

	/* 输入框样式：占据剩余空间 */
	.input-container :deep(.el-textarea) {
		flex: 1;
	}

	/* 按钮组样式：flex布局，间距，垂直居中 */
	.button-group {
		display: flex;
		gap: 8px;
		align-items: center;
	}

	/* 发送按钮样式：高度自适应内容 */
	.send-btn {
		height: fit-content;
	}

	/* 停止按钮样式：高度自适应内容 */
	.stop-btn {
		height: fit-content;
	}

	/* 淡入动画：从透明到不透明，从下往上移动 */
	@keyframes fadeIn {
		from {
			opacity: 0;
			transform: translateY(10px);
		}
		to {
			opacity: 1;
			transform: translateY(0);
		}
	}

	/* 滚动条样式 */
	.conversation-list::-webkit-scrollbar,
	.messages-container::-webkit-scrollbar {
		width: 6px;
	}

	/* 滚动条轨道样式 */
	.conversation-list::-webkit-scrollbar-track,
	.messages-container::-webkit-scrollbar-track {
		background: #f1f1f1;
	}

	/* 滚动条滑块样式 */
	.conversation-list::-webkit-scrollbar-thumb,
	.messages-container::-webkit-scrollbar-thumb {
		background: #c1c1c1;
		border-radius: 3px;
	}

	/* 滚动条滑块悬停样式 */
	.conversation-list::-webkit-scrollbar-thumb:hover,
	.messages-container::-webkit-scrollbar-thumb:hover {
		background: #a8a8a8;
	}

	/* Markdown内容样式：左对齐 */
	.markdown-content {
		text-align: left;
	}

	/* Markdown标题样式：外边距，字重，行高 */
	.markdown-content h1,
	.markdown-content h2,
	.markdown-content h3,
	.markdown-content h4,
	.markdown-content h5,
	.markdown-content h6 {
		margin: 1em 0 0.5em 0;
		font-weight: 600;
		line-height: 1.25;
	}

	/* Markdown一级标题样式：字体大小，底部边框，底部内边距 */
	.markdown-content h1 {
		font-size: 1.5em;
		border-bottom: 1px solid #eaecef;
		padding-bottom: 0.3em;
	}

	/* Markdown二级标题样式：字体大小，底部边框，底部内边距 */
	.markdown-content h2 {
		font-size: 1.3em;
		border-bottom: 1px solid #eaecef;
		padding-bottom: 0.3em;
	}

	/* Markdown三级标题样式：字体大小 */
	.markdown-content h3 {
		font-size: 1.2em;
	}

	/* Markdown段落样式：外边距，行高 */
	.markdown-content p {
		margin: 0.5em 0;
		line-height: 1.6;
	}

	/* Markdown列表样式：左内边距，外边距 */
	.markdown-content ul,
	.markdown-content ol {
		padding-left: 2em;
		margin: 0.5em 0;
	}

	/* Markdown列表项样式：上下外边距 */
	.markdown-content li {
		margin: 0.25em 0;
	}

	/* Markdown引用样式：外边距，内边距，左侧边框，文字颜色 */
	.markdown-content blockquote {
		margin: 0.5em 0;
		padding: 0 1em;
		border-left: 4px solid #dfe2e5;
		color: #6a737d;
	}

	/* Markdown行内代码样式：背景色，内边距，圆角，字体大小，字体族 */
	.markdown-content code {
		background-color: #f6f8fa;
		padding: 0.2em 0.4em;
		border-radius: 3px;
		font-size: 0.85em;
		font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
	}

	/* Markdown代码块样式：背景色，内边距，圆角，水平滚动，外边距 */
	.markdown-content pre {
		background-color: #f6f8fa;
		padding: 1em;
		border-radius: 6px;
		overflow-x: auto;
		margin: 0.5em 0;
	}

	/* Markdown代码块内代码样式：无背景，无内边距，无圆角 */
	.markdown-content pre code {
		background: none;
		padding: 0;
		border-radius: 0;
	}

	/* Markdown表格样式：边框合并，外边距，宽度100% */
	.markdown-content table {
		border-collapse: collapse;
		margin: 0.5em 0;
		width: 100%;
	}

	/* Markdown表格单元格样式：边框，内边距，左对齐 */
	.markdown-content table th,
	.markdown-content table td {
		border: 1px solid #dfe2e5;
		padding: 0.5em 1em;
		text-align: left;
	}

	/* Markdown表格表头样式：背景色，字重 */
	.markdown-content table th {
		background-color: #f6f8fa;
		font-weight: 600;
	}

	/* Markdown链接样式：蓝色文字，无下划线 */
	.markdown-content a {
		color: #0366d6;
		text-decoration: none;
	}

	/* Markdown链接悬停样式：显示下划线 */
	.markdown-content a:hover {
		text-decoration: underline;
	}

	/* Markdown粗体样式：字重600 */
	.markdown-content strong {
		font-weight: 600;
	}

	/* Markdown斜体样式：斜体 */
	.markdown-content em {
		font-style: italic;
	}

	/* 打字机光标样式：行内块，闪烁动画，蓝色，粗体，左外边距 */
	.typing-cursor {
		display: inline-block;
		animation: blink 1s infinite;
		color: #1976d2;
		font-weight: bold;
		margin-left: 2px;
	}

	/* 闪烁动画：50%时间显示，50%时间隐藏 */
	@keyframes blink {
		0%,
		50% {
			opacity: 1;
		}
		51%,
		100% {
			opacity: 0;
		}
	}

	/* 流式消息样式：相对定位 */
	.message-content .streaming {
		position: relative;
	}

	/* 停止生成标签样式 */
	.stopped-tag {
		margin-top: 8px;
		text-align: left;
	}

	/* 消息容器平滑滚动 */
	.messages-container {
		scroll-behavior: smooth;
	}
</style>
